import {
  addRole,
  DeleteRole,
  getPermissions,
  getRoles,
  getUsers,
  putRole,
} from '@/services/ant-design-pro/api';
import { CloseCircleOutlined, PlusOutlined } from '@ant-design/icons';
import type { ProColumns } from '@ant-design/pro-components';
import {
  ModalForm,
  ProFormSelect,
  ProFormText,
  ProFormTreeSelect,
  ProTable,
} from '@ant-design/pro-components';
import { useIntl } from '@umijs/max';
import { App, Button, Card, List, Popconfirm, Tag, Tooltip, Tree, TreeSelect } from 'antd';
import lodash from 'lodash';
import React, { useRef, useState } from 'react';

type GithubIssueItem = {
  url: string;
  id: number;
  number: number;
  title: string;
  labels: {
    name: string;
    color: string;
  }[];
  state: string;
  comments: number;
  created_at: string;
  updated_at: string;
  closed_at?: string;
};

/**
 * 将列表转换为树形结构
 * @param list - 要转换的列表
 * @return 包含树形结构和叶子节点ID的对象
 */

function listTransformTree(list: any[]) {
  const map = new Map<string, any>();
  const result: any[] = [];
  const leafIds: { value: string | number; label: string }[] = [];

  // 创建节点副本并初始化 children 为 []
  const nodes = list.map((item) => ({ ...item, children: [] }));

  // 构建 id 映射
  for (const node of nodes) {
    map.set(node.id, node);
  }

  // 构建树结构
  for (const node of nodes) {
    if (node.parentId) {
      const parent = map.get(node.parentId);
      if (parent) {
        parent.children.push(node);
      }
    } else {
      result.push(node);
    }
  }

  // 遍历树收集叶子节点
  function collectLeafIds(node: any) {
    leafIds.push({
      value: node.id,
      label: node.name,
    });
    if (node.children && node.children.length > 0) {
      node.children.forEach(collectLeafIds);
    }
    // if (!node.children || node.children.length === 0) {
    //   leafIds.push(node.id);
    // } else {
    //   node.children.forEach(collectLeafIds);
    // }
  }

  result.forEach(collectLeafIds);

  return { tree: result, leafIds };
}

const valueMap: any = {};
function loops(list: any, parent?: any) {
  return (list || []).map(({ children, id }: { children?: any; id: any }) => {
    const node: any = (valueMap[id] = {
      parent,
      id,
    });
    node.children = loops(children, node);
    return node;
  });
}
function getPath(id: any) {
  const path = [];
  let current = valueMap[id];
  while (current) {
    path.unshift(current.id);
    current = current.parent;
  }
  return path;
}

export function collectIdsFromTree(tree: any[], targetId: string): string[] {
  let result: string[] = [];
  function collectAllIds(node: any) {
    result.push(node.id);
    if (Array.isArray(node.children)) {
      for (const child of node.children) {
        collectAllIds(child);
      }
    }
  }
  function findNodeAndCollectIds(node: any) {
    if (node.id === targetId) {
      collectAllIds(node);
      return true;
    }
    if (Array.isArray(node.children)) {
      for (const child of node.children) {
        if (findNodeAndCollectIds(child)) {
          return true;
        }
      }
    }
    return false;
  }

  for (const root of tree) {
    if (findNodeAndCollectIds(root)) break;
  }

  return result;
}

const Character: React.FC<any> = ({ searchName, transTab }) => {
  const [addOrEdit, setAddOrEdit] = useState('add');
  const [currentRow, setCurrentRow] = useState<any>();
  const [modalVisit, setModalVisit] = useState(false);
  // const TreeSelectRef = useRef<any>();

  const [selectedTreeData, setSelectedTreeData] = useState<any>([]);
  const [treeData, setTreeData] = useState([]);
  const actionRef = useRef<any>();
  const intl = useIntl();
  const { message } = App.useApp();

  async function requestData(val: any) {
    const res: any = {
      data: [],
      total: 0,
    };
    const data = await getRoles({ params: val });
    if (data.code === 0) {
      res.data = data.msg;
      res.total = data.options.total;
      res.data.forEach((item: any) => {
        const { tree, leafIds } = listTransformTree(item.permission || []);
        item.permissionTree = tree;
        item.permissionLeafIds = leafIds;
      });
    }
    return Promise.resolve(res);
  }

  const getTreeData = async () => {
    const data = await getPermissions();
    if (data.code === 0) {
      loops(data.msg);
      setTreeData(data.msg);
    } else {
      message.info(data.msg);
    }
  };
  const columns: ProColumns<GithubIssueItem>[] = [
    {
      title: 'ID',
      dataIndex: 'id',
      ellipsis: true,
      hideInSearch: true,
    },
    {
      title: intl.formatMessage({
        id: 'component.roleName',
        defaultMessage: '角色名',
      }),
      dataIndex: 'name',
      ellipsis: true,
      initialValue: searchName,
      // tooltip: '标题过长会自动收缩',
    },
    {
      title: intl.formatMessage({
        id: 'component.usersWithRoles',
        defaultMessage: '拥有角色的用户',
      }),
      dataIndex: 'users',
      hideInSearch: true,
      ellipsis: true,
      render(dom, record: any) {
        return (
          record.users &&
          record.users.map((val: any, i: any) => (
            <Tooltip key={i} title={`手机号：` + val.phone}>
              <Tag
                key={i}
                closable
                style={{ cursor: 'pointer' }}
                color="orange"
                onClick={(e: any) => transTab('用户管理', e.target.outerText)}
                onClose={async () => {
                  const data = lodash.cloneDeep(record);
                  data.users = data.users.filter((item: any) => {
                    return item.id !== val.id;
                  });
                  const res: any = await putRole({ data });
                  if (res.code === 0) {
                    record.users = record.users.filter((item: any) => {
                      return item.id !== val.id;
                    });
                    message.success('角色修改成功');
                  } else {
                    message.info(res.msg);
                    actionRef.current?.reload();
                  }
                }}
              >
                {val.username}
              </Tag>
            </Tooltip>
          ))
        );
      },
    },
    {
      title: intl.formatMessage({
        id: 'pages.searchTable.titleOption',
        defaultMessage: '操作',
      }),
      width: '120px',
      valueType: 'option',
      ellipsis: true,
      key: 'option',
      render: (text, record: any) => [
        <Button
          onClick={async () => {
            await getTreeData();
            setAddOrEdit('edit');
            setCurrentRow(record);
            setSelectedTreeData(record.permissionLeafIds || []);
            setModalVisit(true);
          }}
          key="edit"
          size="small"
          type="primary"
          ghost
        >
          {intl.formatMessage({
            id: 'component.edit',
            defaultMessage: '编辑',
          })}
        </Button>,
        <Popconfirm
          key="delete"
          title={intl.formatMessage({
            id: 'component.deleteRole',
            defaultMessage: '删除角色',
          })}
          description={intl.formatMessage(
            {
              id: 'component.requireDeleteRole',
              defaultMessage: '是否删除（{name}）角色？',
            },
            { name: record.name },
          )}
          onConfirm={async () => {
            const res: any = await DeleteRole({ data: { id: record.id } });
            if (res.code === 0) {
              message.success(
                intl.formatMessage({
                  id: 'component.deleteRoleSuccess',
                  defaultMessage: '删除角色成功',
                }),
              );
              actionRef.current?.reload();
            } else {
              message.info(res.msg);
            }
          }}
          onCancel={() => {}}
          okText="Yes"
          cancelText="No"
        >
          <Button size="small" danger>
            {intl.formatMessage({
              id: 'component.delete',
              defaultMessage: '删除',
            })}
          </Button>
        </Popconfirm>,
      ],
    },
  ];

  const expandedRowRender = (record: any) => {
    let data = [];
    if (record.permissionTree && record.permissionTree.length > 0) {
      data = record.permissionTree;
    } else {
      data = [];
    }
    return (
      <List
        grid={{
          gutter: 16,
          xs: 1,
          sm: 2,
          md: 4,
          lg: 4,
          xl: 6,
          xxl: 3,
        }}
        dataSource={data}
        renderItem={(val: any, i) => (
          <List.Item key={i}>
            <Card
              styles={{
                title: {
                  color: 'red',
                },
                header: {
                  color: 'blue',
                },
              }}
              title={
                <CloseCircleOutlined
                  onClick={async () => {
                    let requestData = {
                      id: record.id,
                      name: record.name,
                      permission: [],
                      users: [],
                    };
                    requestData.users = record.users.map((item: any) => {
                      return {
                        id: item.id,
                      };
                    });
                    let deleteIds = collectIdsFromTree(record.permissionTree, val.id);
                    requestData.permission = record.permission
                      .filter((item: any) => {
                        return !deleteIds.includes(item.id);
                      })
                      .map((item: any) => {
                        return {
                          id: item.id,
                        };
                      });
                    const res: any = await putRole({ data: requestData });
                    if (res.code === 0) {
                      record.users = record.users.filter((item: any) => {
                        return item.id !== val.id;
                      });
                      message.success('角色修改成功');
                    } else {
                      message.info(res.msg);
                    }
                    actionRef.current?.reload();
                  }}
                />
              }
            >
              <Tree
                showLine
                defaultExpandAll={true}
                fieldNames={{
                  key: 'id',
                  title: 'name',
                }}
                treeData={[val]}
              />
            </Card>
          </List.Item>
        )}
      />
    );
  };
  const onReset = () => {
    actionRef.current.reset();
  };

  return (
    <>
      <ModalForm
        title={
          addOrEdit === 'add'
            ? intl.formatMessage({
                id: 'component.createRole',
                defaultMessage: '新建角色',
              })
            : intl.formatMessage({
                id: 'component.modifyRole',
                defaultMessage: '修改角色',
              })
        }
        open={modalVisit}
        autoFocusFirstInput
        modalProps={{
          destroyOnClose: true,
          onCancel: () => setModalVisit(false),
        }}
        width={400}
        onFinish={async (val: any) => {
          let res: any;

          val.permission = lodash.uniqBy(
            selectedTreeData.map((item: any) => {
              return {
                id: item.value,
              };
            }),
            'id',
          );
          val.users =
            val.users &&
            val.users.map((item: any) => {
              return {
                id: item,
              };
            });
          if (addOrEdit === 'add') {
            res = await addRole({ data: val });
            if (res.code === 0) {
              message.success('角色添加成功');
              actionRef.current?.reload();
            } else {
              message.info(res.msg);
            }
          } else {
            res = await putRole({ data: { ...val, id: currentRow.id } });
            if (res.code === 0) {
              message.success('角色修改成功');
              actionRef.current?.reload();
            } else {
              message.info(res.msg);
            }
          }
          setModalVisit(false);
        }}
      >
        <ProFormText
          name="name"
          label={intl.formatMessage({
            id: 'component.roleName',
            defaultMessage: '角色名',
          })}
          placeholder={intl.formatMessage({
            id: 'component.enterRoleName',
            defaultMessage: '请输入角色名',
          })}
          rules={[
            {
              required: true,
              message: intl.formatMessage({
                id: 'component.enterRoleName',
                defaultMessage: '请输入角色名',
              }),
            },
          ]}
          initialValue={currentRow && currentRow.name}
        />
        <ProFormTreeSelect
          name="permission"
          label={intl.formatMessage({
            id: 'component.permission',
            defaultMessage: '权限',
          })}
          placeholder={intl.formatMessage({
            id: 'component.enterPermissionName',
            defaultMessage: '请输入权限名',
          })}
          fieldProps={{
            value: selectedTreeData,
            showCheckedStrategy: TreeSelect.SHOW_ALL,
            treeDefaultExpandAll: true,
            treeData: treeData,
            // defaultValue: () => {
            //   console.log(currentRow, "currentRow")
            //   return currentRow && currentRow.permissionLeafIds ? currentRow.permissionLeafIds : [];
            // },
            treeCheckable: true,
            treeCheckStrictly: true,
            multiple: true,
            fieldNames: {
              label: 'name',
              value: 'id',
              children: 'children',
            },
            onChange: (val: any, a: any, b: any) => {
              let finalSelectedTreeData: any = [];
              if (b.checked === true) {
                const pathsIdListParent = getPath(b.triggerValue);
                finalSelectedTreeData = [
                  ...selectedTreeData,
                  ...pathsIdListParent.map((item: any) => {
                    return {
                      value: item,
                    };
                  }),
                ];
                lodash.uniqBy(selectedTreeData, 'value');
              } else if (b.checked === false) {
                const pathsIdListSon = collectIdsFromTree(treeData, b.triggerValue);
                finalSelectedTreeData = selectedTreeData.filter((item: any) => {
                  return !pathsIdListSon.includes(item.value);
                });
              }
              setSelectedTreeData(finalSelectedTreeData);
            },
          }}
        ></ProFormTreeSelect>
        <ProFormSelect
          name="users"
          label={intl.formatMessage({
            id: 'component.usersWithThisRole',
            defaultMessage: '拥有该角色的用户',
          })}
          fieldProps={{
            mode: 'multiple',
            fieldNames: {
              label: 'username',
              value: 'id',
            },
          }}
          placeholder={intl.formatMessage({
            id: 'component.selectUser',
            defaultMessage: '请选择用户',
          })}
          initialValue={(function () {
            let res: any = [];
            res =
              currentRow &&
              currentRow.users &&
              currentRow.users.map((item: any) => {
                return item.id;
              });
            return res;
          })()}
          request={async () => {
            let res: any = [];
            const data = await getUsers({ params: { current: 1, pageSize: 999999999 } });
            if (data.code === 0) {
              res = data.msg;
            }
            return Promise.resolve(res);
          }}
        />
      </ModalForm>
      <ProTable<GithubIssueItem>
        onReset={onReset}
        expandable={{
          expandedRowRender,
          rowExpandable: (record: any) => {
            // 这里设置当状态为 'closed' 的行不显示 expandable
            if (record.permission && record.permission.length <= 0) {
              record.state = 'closed';
            }
            return record.state !== 'closed';
          },
        }}
        columns={columns}
        actionRef={actionRef}
        request={requestData}
        editable={{
          type: 'multiple',
        }}
        scroll={{
          x: true,
        }}
        columnsState={{
          persistenceKey: 'pro-table-singe-demos',
          persistenceType: 'localStorage',
          defaultValue: {
            option: { fixed: 'right', disable: true },
          },
          onChange() {},
        }}
        rowKey="id"
        search={{
          labelWidth: 'auto',
        }}
        options={{
          setting: {
            listsHeight: 400,
          },
        }}
        pagination={{}}
        dateFormatter="string"
        headerTitle={intl.formatMessage({
          id: 'pages.admin.roleManagement',
          defaultMessage: '角色管理',
        })}
        toolBarRender={() => [
          <Button
            key="button"
            icon={<PlusOutlined />}
            onClick={async () => {
              await getTreeData();
              setSelectedTreeData([]);
              setAddOrEdit('add');
              setCurrentRow(null);
              setModalVisit(true);
            }}
            type="primary"
          >
            {intl.formatMessage({
              id: 'pages.searchTable.new',
              defaultMessage: '新建',
            })}
          </Button>,
        ]}
      />
    </>
  );
};

export default Character;
